package com.sheep.service.impl;

import com.sheep.common.utils.JwtTokenUtil;
import com.sheep.dao.RbacAdminRoleRelationDao;
import com.sheep.dto.AdminUserDetails;
import com.sheep.mbg.mapper.RbacAdminMapper;
import com.sheep.mbg.model.RbacAdmin;
import com.sheep.mbg.model.RbacAdminExample;
import com.sheep.mbg.model.RbacPermission;
import com.sheep.service.RbacAdminService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class RbacAdminServiceImpl implements RbacAdminService {
    private static final Logger LOGGER = LoggerFactory.getLogger(RbacAdminServiceImpl.class);

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private RbacAdminMapper adminMapper;
    @Autowired
    private RbacAdminRoleRelationDao adminRoleRelationDao;

    @Override
    public RbacAdmin getAdminByUsername(String username) {

        RbacAdminExample example = new RbacAdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<RbacAdmin> adminList = adminMapper.selectByExample(example);
        if (adminList != null && adminList.size() > 0) {

            return adminList.get(0);
        }
        return null;
    }

    @Override
    public UserDetails loadUserByUsername(String username) {
        //获取用户信息
        RbacAdmin admin = getAdminByUsername(username);
        if (admin != null) {
            List<RbacPermission> permissionList = getPermissionList(admin.getId());
            return new AdminUserDetails(admin, permissionList);
        }
        throw new UsernameNotFoundException("用户名或密码错误");
    }

    @Override
    public RbacAdmin register(RbacAdmin umsAdminParam) {
        RbacAdmin rbacAdmin = new RbacAdmin();
        BeanUtils.copyProperties(umsAdminParam, rbacAdmin);
        rbacAdmin.setCreateTime(new Date());
        rbacAdmin.setStatus(1);
        //查询是否有相同用户名的用户
        RbacAdminExample example = new RbacAdminExample();
        example.createCriteria().andUsernameEqualTo(rbacAdmin.getUsername());
        List<RbacAdmin> umsAdminList = adminMapper.selectByExample(example);
        if (umsAdminList.size() > 0) {
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(rbacAdmin.getPassword());
        rbacAdmin.setPassword(encodePassword);
        adminMapper.insert(rbacAdmin);
        return rbacAdmin;
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        //密码需要客户端加密后传递
        try {
            UserDetails userDetails = loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new RuntimeException("密码不正确");
            }
            if (!userDetails.isEnabled()) {
                throw new RuntimeException("帐号已被禁用");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
            updateLoginTimeByUsername(username);

        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

    /**
     * 根据用户名修改登录时间
     */
    private void updateLoginTimeByUsername(String username) {
        RbacAdmin record = new RbacAdmin();
        record.setLoginTime(new Date());
        RbacAdminExample example = new RbacAdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        adminMapper.updateByExampleSelective(record, example);
    }

    @Override
    public List<RbacPermission> getPermissionList(Long adminId) {
        return adminRoleRelationDao.getPermissionList(adminId);
    }
}
